From: kaf24@firebug.cl.cam.ac.uk Date: Wed, 17 May 2006 22:43:32 +0000 (+0100) Subject: Allow to specify different time-of-day clock offsets for HVM guests. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~16047^2~52 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/success//%22http:/www.example.com/cgi/success/?a=commitdiff_plain;h=bca9460e9462ee362ef3f051a8b44622e32c9e64;p=xen.git Allow to specify different time-of-day clock offsets for HVM guests. There are some usage scenarios in which differing user domains want to be using different base TOD clocks. This patch adds the ability to specify the base TOD time difference. The patch also adds a hook point to notify another entity when the domain changes this offset. This might occur, for instance, on a Linux domain using hwclock -w. Signed-off-by: Ben Thomas --- diff --git a/tools/ioemu/hw/mc146818rtc.c b/tools/ioemu/hw/mc146818rtc.c index 9d4cbed90b..cf0f2c029e 100644 --- a/tools/ioemu/hw/mc146818rtc.c +++ b/tools/ioemu/hw/mc146818rtc.c @@ -178,10 +178,27 @@ static inline int from_bcd(RTCState *s, int a) } } +static void send_timeoffset_msg(time_t delta) +{ + +/* This routine is used to inform another entity that the + base time offset has changed. For instance, if you + were using xenstore, you might want to write to the store + at this point. Or, you might use some other method. + Whatever you might choose, here's a hook point to implement it. + + One item of note is that this delta is in addition to + any existing offset you might be already using. */ + + return; +} + static void rtc_set_time(RTCState *s) { struct tm *tm = &s->current_tm; - + time_t before, after; + + before = mktime(tm); tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]); tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]); tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f); @@ -193,6 +210,12 @@ static void rtc_set_time(RTCState *s) tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]); tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1; tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + 100; + + /* Compute, and send, the additional time delta + We could compute the total time delta, but this is + sufficient, and simple. */ + after = mktime(tm); + send_timeoffset_msg(after-before); } static void rtc_copy_date(RTCState *s) diff --git a/tools/ioemu/hw/pc.c b/tools/ioemu/hw/pc.c index 08106fc75a..d762f0e9ee 100644 --- a/tools/ioemu/hw/pc.c +++ b/tools/ioemu/hw/pc.c @@ -118,7 +118,7 @@ static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd) } /* hd_table must contain 4 block drivers */ -static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table) +static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table, time_t timeoffset) { RTCState *s = rtc_state; int val; @@ -129,6 +129,7 @@ static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_ /* set the CMOS date */ time(&ti); + ti += timeoffset; if (rtc_utc) tm = gmtime(&ti); else @@ -381,7 +382,7 @@ extern int acpi_init(unsigned int base); void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename) + const char *initrd_filename, time_t timeoffset) { SerialState *sp; char buf[1024]; @@ -577,7 +578,7 @@ void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device, floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); - cmos_init(ram_size, boot_device, bs_table); + cmos_init(ram_size, boot_device, bs_table, timeoffset); acpi_init(0x8000); /* must be done after all PCI devices are instanciated */ diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c index 54ec0967fc..08e38449bb 100644 --- a/tools/ioemu/vl.c +++ b/tools/ioemu/vl.c @@ -147,6 +147,7 @@ int repeat_key = 1; TextConsole *vga_console; CharDriverState *serial_hds[MAX_SERIAL_PORTS]; int xc_handle; +time_t timeoffset = 0; /***********************************************************/ /* x86 ISA bus support */ @@ -2247,9 +2248,10 @@ void help(void) "-s wait gdb connection to port %d\n" "-p port ioreq port for xen\n" "-d domain domain that we're serving\n" - "-domain-namn domain name that we're serving\n" + "-domain-name domain name that we're serving\n" "-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n" "-L path set the directory for the BIOS and VGA BIOS\n" + "-timeoffset time offset (in seconds) from local time (Xen)\n" #ifdef USE_CODE_COPY "-no-code-copy disable code copy acceleration\n" #endif @@ -2347,6 +2349,7 @@ enum { QEMU_OPTION_monitor, QEMU_OPTION_domainname, QEMU_OPTION_serial, + QEMU_OPTION_timeoffset, QEMU_OPTION_loadvm, QEMU_OPTION_full_screen, QEMU_OPTION_vgaacc, @@ -2420,6 +2423,7 @@ const QEMUOption qemu_options[] = { { "std-vga", 0, QEMU_OPTION_std_vga }, { "monitor", 1, QEMU_OPTION_monitor }, { "domain-name", 1, QEMU_OPTION_domainname }, + { "timeoffset", HAS_ARG, QEMU_OPTION_timeoffset }, { "serial", 1, QEMU_OPTION_serial }, { "loadvm", HAS_ARG, QEMU_OPTION_loadvm }, { "full-screen", 0, QEMU_OPTION_full_screen }, @@ -2936,7 +2940,10 @@ int main(int argc, char **argv) case QEMU_OPTION_domainname: strncat(domain_name, optarg, sizeof(domain_name) - 20); break; - + case QEMU_OPTION_timeoffset: + timeoffset = strtol(optarg, NULL, 0); + break; + } } } @@ -3227,7 +3234,7 @@ int main(int argc, char **argv) #if defined(TARGET_I386) pc_init(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, - kernel_filename, kernel_cmdline, initrd_filename); + kernel_filename, kernel_cmdline, initrd_filename, timeoffset); #elif defined(TARGET_PPC) ppc_init(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, diff --git a/tools/ioemu/vl.h b/tools/ioemu/vl.h index 5b6b4ce343..54a84c6bd4 100644 --- a/tools/ioemu/vl.h +++ b/tools/ioemu/vl.h @@ -679,7 +679,7 @@ int pit_get_out(PITState *pit, int channel, int64_t current_time); void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, - const char *initrd_filename); + const char *initrd_filename, time_t timeoffset); /* ppc.c */ void ppc_init (int ram_size, int vga_ram_size, int boot_device,